<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Grid Search and Highlight Demo</title>

<link rel="stylesheet" type="text/css" href="../theme-local-1.6.0.css" />
<style type="text/css">
body {
    font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
    font-size: 11px;
}

#debugPanel pre {
    font-family: "Lucida Console", "Courier New", Courier, monospace;
}

div.container {
    border: 0px solid green;
    margin: 10px;
}
</style>

<script type="text/javascript">
var djConfig = {
    isDebug: true,
    parseOnLoad: true,
    locale: "zh",
    extraLocale: ["en"],
    baseUrl: "../script/dojo-1.6.0/dojo/",
    modulePaths: {
        "demo": "../../../script/demo",
        "com": "../../../script/com"
    }
};
</script>
<script type="text/javascript" src="../script/dojo-1.6.0/dojo/dojo.js"></script>
<script type="text/javascript" src="../script/dojo-require.js"></script>
<script type="text/javascript">
    dojo.require("dojox.grid.enhanced.plugins.exporter.CSVWriter");
</script>
<script type="text/javascript" src="../script/utils.js"></script>
<script type="text/javascript" src="../script/grid.js"></script>
<script type="text/javascript" src="../script/smd/grid.js"></script>
<script type="text/javascript">
function debug(messages) {
    var msg = demo.utils._getDebugMsg.apply(null, arguments);
    console.debug(msg);

    var msgDiv = dojo.byId("debugPanelContent");
    msgDiv.innerHTML = msg;
}

function append(messages) {
    var msg = demo.utils._getDebugMsg.apply(null, arguments);

    var msgDiv = dojo.byId("debugPanelContent");
    msgDiv.innerHTML += "\n" + msg;
}

function show(id) {
    demo.utils.show(id);
}

function hide(id) {
    demo.utils.hide(id);
}
</script>
<style type="text/css">
@import "../css/rounded-button.css";
@import "../css/rounded-corners.css";

body {
    padding: 10px;
}

.gridContainer {
    width: 100%;
    height: 300px;
}

/* Column selector pane */
.column-selector-pane {
    vertical-align: top;
}

.column-selector-pane li {
    list-style: none;
}

.highlight {
    background-color: yellow;
}

.smd-cell-captain {
    background-color: #99bbee;
    color: #000000;
    font-weight: bold;
}

.smd-cell-number {
    text-align: right;
}

a:hover {
    color: #6699cc;
}
</style>
<script type="text/javascript">
///////////////////////////////////////////////////////
if (!("grid" in demo)) {
    demo.grid = {};
}

demo.grid.makeGridRowSet = function(data) {
    var items = data.items || [];

    // TODO: update row orders
    var key = "orders";
    var orders = dojox.storage.get(key);
    if (orders) {
        // force to based on server
        var itemMap = {};
        dojo.forEach(items, function(item) {
            var id = item.id;
            itemMap[id] = item;
        });

        var orderedItems = [];
        for (var i = 0; i < orders.length; i++) {
            var id = orders[i];
            var item = itemMap[id];
            if (!item) {
                // not match
                console.warn("client has more items than server");
                return;
            }

            delete itemMap[id];
            orderedItems.push(item);
        }

        for (var key in itemMap) {
            if (key) {
                // TODO: grid only cache one page nodes
                console.warn("server has more items than client");
                //return;
            }
        }

        items = orderedItems;
    }

    return items;
};

demo.grid.makeFormatterParameters = function() {
    var parameters = [];

    parameters.push({field: "id"}); // {0}

    var rowIndexMapping = function(value, rowIndex) {
        return rowIndex;
    };
    parameters.push({mapping: rowIndexMapping}); // {1}

    return parameters;
};

demo.grid.makeColumnDefs = function(data) {
    var columnDefs = [];

    columnDefs.push({
        title: "ID",
        field: "id",
        link: "./id/{0}",
        width: "100px"
    });

    columnDefs.push({
        title: "Name",
        field: "name",
        link: "./name/{0}",
        width: "30%",
        editable: true,
        type: dojox.grid.cells._Widget,
        widgetClass: dijit.form.ValidationTextBox,
        widgetProps: {required: true, regExp: "^[^\\s]+.*"}
    });

    columnDefs.push({
        title: "Type",
        field: "type",
        link: "./type/{0}",
        relWidth: 1,
        editable: true,
        type: dojox.grid.cells.ComboBox,
        options: ["continent", "country", "city"]
    });

    columnDefs.push({
        title: "Population",
        field: "population",
        link: "./population/{0}",
        relWidth: 1
    });

    columnDefs.push({
        title: "Operation",
        field: "_item",
        content: "Rename",
        onclick: "rename({1});",
        relWidth: 1
    });

    return columnDefs;
};

demo.grid.buildGrid = function(nodeId, data) {
    console.time("grid");
    // initialize tree grid
    var grid = dijit.byId("grid");

    if (!grid) {
        //dojo.byId("title").innerHTML = data.metadata.title;
        //smd.grid.formatMetadata(dojo.byId("metadata"), data.metadata.description);
        //dojo.byId("footer").innerHTML = data.metadata.footer || "xxx Confidential";

        // rows
        var rows = demo.grid.makeGridRowSet(data);
        console.info("store", rows);

        // formatter parameters
        var formatterParameters = demo.grid.makeFormatterParameters();

        // column definitions for grid
        var columnDefs = demo.grid.makeColumnDefs(data);
        console.info("columnDefs", columnDefs);

        // parameters for grid
        var params = {
            id: "grid",
            //autoHeight: 10,
            height: "300px",
            noDataMessage: "Your selections have yielded no data. Please refine them and try again."
        };

        var configuration = {
            id: params.id,
            node: params.id,
            identifier: "id",
            label: "name",
            plugins: {
                nestedSorting: true,
                dnd: true,
                indirectSelection: {
                    headerSelector: true
                },
                exporter: true
            },
            formatterParameters: formatterParameters,
            columnDefs: columnDefs,
            params: params
        };
        var grid = smd.grid.buildGrid(rows, configuration);

        // event for apply cell edit
        dojo.connect(grid, "onApplyCellEdit", onApplyCellEdit);

        // event for save row orders
        dojo.connect(grid, "updateRows", onUpdateRows);

        // subscribe the row movement notification
        dojo.subscribe(grid.rowMovedTopic, function(grid) {
            onUpdateRows();
        });
    }
    console.timeEnd("grid");
};

//////////////////////////////
dojo.ready(function() {
    dojo.byId('version').innerHTML = 'Version ' + dojo.version;

    debug("loading");

    var url = "../data/countries.json";
    dojo.xhrGet({
        url: url,
        handleAs: "json",
        load: function(response, ioargs) {
            debug("loaded");
            demo.grid.buildGrid("grid", response);

            // search
            initSearch();
        },
        error: function(error) {
            debug(error);
        }
    });
});

//////////////////////////////
function initSearch() {
    smd.grid.getSearchKeyword = getSearchKeyword;
    smd.grid.getSearchField = getSearchField;

    initFieldSelector(dijit.byId("searchField"));
    dojo.connect(dijit.byId("searchKeyword"), "onKeyUp", doSearch);
    dojo.connect(dijit.byId("searchField"), "onChange", doSearch);
}

function getSearchKeyword() {
    var textbox = dijit.byId("searchKeyword");
    var keyword = textbox.get("value") || null;

    return keyword;
}

function getSearchField() {
    var fieldSelector = dijit.byId("searchField");
    var field = fieldSelector.get("value");

    return field;
}

function initFieldSelector(selector) {
    var data = {
        identifier: "field",
        label: "name",
        items: [
            {
                field: "all",
                name: "All",
                show: true
            }
        ]
    };

    var store = new dojox.data.AndOrWriteStore({
        data: data
    });

    selector.set("store", store);
    selector.set("query", {show: true});
    selector.set("value", "all");

    var grid = dijit.byId("grid");
    var allColumns = smd.grid.getGridColumns(grid);
    dojo.forEach(allColumns, function(column) {
        store.newItem(column);
    });
}

function updateFieldSelector(visibleColumns) {
    var selector = dijit.byId("searchField");
    var store = selector.store;
    var searchField = getSearchField();

    store.fetch({
        query: {
            complexQuery: "NOT field:'all'"
        },
        onComplete: function(items) {
            dojo.forEach(items, function(item) {
                var field = store.getValue(item, "field", null);
                var isVisible = dojo.some(visibleColumns, function(column) {
                    return field === column.field;
                });

                if (!isVisible) {
                    if (field === searchField) {
                        // Current selected option will be deleted, so select "all" instead.
                        selector.set("value", "all");
                    }
                }

                store.setValue(item, "show", isVisible);
            });
        }
    });
}

////////////////////////////////////////
function rename(rowIndex) {
    var grid = dijit.byId("grid");

    var matches = dojo.filter(grid.layout.cells, function(cell) {
        return (cell.field === "name");
    });

    if (matches.length > 0) {
        var cell = matches[0];
        console.info("rename", rowIndex);
        grid.edit.setEditCell(cell, rowIndex, true);
    }
}

function onApplyCellEdit(value, rowIndex, field) {
    var grid = this;
    var item = grid.getItem(rowIndex);
    var store = grid.store;
    var identity = store.getIdentity(item);

    debug("upload to server:", identity, value);
}

function saveOrders(items) {
    var grid = dijit.byId("grid");
    var store = grid.store;

    var sortedIds = dojo.map(items, function(item) {
        return store.getIdentity(item);
    });

    var key = "orders";
    dojox.storage.put(key, sortedIds, function(status, keyName) {
        if (status === dojox.storage.FAILED) {
            alert("You do not have permission to store data for this web site.");
        } else if (status == dojox.storage.SUCCESS) {
            var orders = dojox.storage.get(keyName);
            //console.info("orders", orders);
        }
    });
}

function onUpdateRows() {
    var grid = dijit.byId("grid");

    // TODO: _StoreLayer
    grid._storeLayerFetch({
        //query: grid.query,
        sort: grid.getSortProps(),
        //queryOptions: grid.queryOptions,
        //isRender: false,
        onComplete: saveOrders,
        onError: function(err) {
            alert(err);
        }
    });
}

////////////////////////////////////////
function doSearch(e) {
    var keyword = smd.grid.getSearchKeyword();
    var field = smd.grid.getSearchField();

    var grid = dijit.byId("grid");
    smd.grid.search(grid, keyword, field);
}

// showColumnSelectorDialogButton
function showColumnSelectorDialog() {
    var grid = dijit.byId("grid");
    demo.grid.buildColumnSelectorContainer(grid, "columnSelectorContainer", 10);
    dijit.byId("gridColumnsDialog").show();
}

// showColumnsButton
function showColumns() {
    var grid = dijit.byId("grid");

    demo.grid.showSelectedColumns(grid, updateFieldSelector);
    dijit.byId("gridColumnsDialog").hide();
}

function showColumns() {
    var grid = dijit.byId("grid");

    demo.grid.showSelectedColumns(grid, updateFieldSelector);
    dijit.byId("gridColumnsDialog").hide();
}

function removeSelectedRows() {
    var grid = dijit.byId("grid");
    grid.removeSelectedRows();
}

function printPreview() {
    var grid = dijit.byId("grid");
    grid.exportGrid("csv", {}, function(str) {
        console.debug(str);
    });
}
</script>
</head>
<body class="claro">

  <h2 id="version">Unknown Version</h2>

  <div id="main" class="container">

    <div id="titlePanel" dojoType="dijit.TitlePane" title="Panel" style="">
      <div id="resizablePanel" style="position:relative; padding: 10px; border:1px solid black;">

        <!-- Content -->
        <div class="content">
            <div id="title" style="font-weight: bold;"></div>
            <!-- grid toolbar -->
            <div id="gridToolbarContainer">
              <!-- Search Box -->
              <label for="searchKeyword">Search:</label><input id="searchKeyword" type="text" dojoType="dijit.form.TextBox" />
              <!-- Field Selector -->
              <label for="searchField">within:</label>
              <select id="searchField" dojoType="dijit.form.FilteringSelect"></select>
            </div>
            <!-- grid -->
            <div id="grid"></div>
            <div id="metadata"></div>
            <div id="footer" style="text-align: center; font-weight: bold; font-size: smaller; color: #880000;"></div>
        </div>

        <!-- Resize Handle -->
        <div id="resizeHandle" dojoType="dojox.layout.ResizeHandle" targetId="resizablePanel"></div>
      </div>
    </div>

    <!-- Button Panel -->
    <div dojoType="dojo.dnd.Moveable">
      <div id="buttonPanel" dojoType="dijit.TitlePane" title="Button Panel" style="">
        <!-- Button -->
        <button dojoType="dijit.form.Button" title="Click to clear data" onClick="dojox.storage.remove('orders');">Clear Cache</button>
        <!-- Button -->
        <button dojoType="dijit.form.Button" title="Click to print preview" onClick="printPreview();">Print preview</button>

        <!-- Show "Select columns to display" dialog -->
        <button dojoType="dijit.form.Button" iconClass="dijitEditorIcon dijitEditorIconFullScreen" title="Show columns dialog" onClick="showColumnSelectorDialog();">Select columns</button>

        <!-- Drop Down Button -->
        <button dojoType="dijit.form.DropDownButton" iconClass="noteIcon" title="Select columns" value="Select columns" menu="">
          <span>Select columns</span>
          <!-- Header Menu -->
          <div dojoType="dijit.Menu" id="headerMenu" style="display: none;">
            <div dojoType="dojox.widget.PlaceholderMenuItem" label="GridColumns"></div>
          </div>
        </button>

        <!-- Restore columns -->
        <button dojoType="dijit.form.Button" title="Restore columns" onClick="restoreColumns();">Restore</button>

        <!-- Remove selected rows -->
        <button dojoType="dijit.form.Button" title="Remove selected row(s)" onClick="removeSelectedRows();">Remove</button>

      </div>
    </div>
  </div>

  <!-- Debug Panel -->
  <div id="debugPanel" dojoType="dojox.layout.FloatingPane" title="Console" resizable="true" dockable="true" style="position: absolute; bottom: 20px; right: 20px; width: 500px; height: 150px;">
    <pre id="debugPanelContent"></pre>
  </div>

  <div id="instruction_1" dojoType="dojox.layout.FloatingPane" title="Help" resizable="true" dockable="true" style="position: absolute; top: 20px; right: 20px; width: 300px;">
    Override dojox/grid/cells/dijit.js line 35:
    <pre>
getValue: function(inRowIndex){
    var value = this.widget.get("value");
    if (this.widget.isValid && !this.widget.isValid()) {
        value = undefined; // indicate invalid value
    }
    return value;
},
    </pre>
  </div>

  <!-- Show Columns Dialog -->
  <div dojoType="dijit.Dialog" id="gridColumnsDialog" title="Select Columns" style="display: none;">
    <div id="columnSelectorContainer"></div>
    <div style="clear: both;" class="hrule-dots">&nbsp;</div>
    <div id="showColumnsButton" dojoType="dijit.form.Button" onClick="showColumns();">Show columns</div>
    <div id="cancelSelectColumnsButton" dojoType="dijit.form.Button" onClick="dijit.byId('gridColumnsDialog').hide();">Cancel</div>
  </div>

  <!-- Toaster -->
  <div dojoType="dojox.widget.Toaster" id="toaster" positionDirection="br-up" messageTopic="toasterMessageTopic"></div>
</body>
</html>
